#include "GCThread.h"


namespace gcstock
{
    GC_Mutex::GC_Mutex(GC_Mutex::TYPE t)
    {
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr,t);
        
        pthread_mutex_init(&_mutex, &attr);
        pthread_mutexattr_destroy(&attr);
        return;
    }
    
    GC_Mutex::~GC_Mutex()
    {
        pthread_mutex_destroy(&_mutex);
        return;
    }
    
    void GC_Mutex::lock()
    {
        pthread_mutex_lock(&_mutex);
        return;
    }
    
    void GC_Mutex::unlock()
    {
        pthread_mutex_unlock(&_mutex);
        return;
    }

    void GC_Cond::wait()
    {
        GC_Guard guard(mutex);
        pthread_cond_wait(&cond,&mutex);
        return;
    }
    
    void GC_Cond::signal()
    {
        GC_Guard guard(mutex);
        // Check condition
        
        pthread_cond_signal(&cond);
        return;
    }
    
    void GC_Task_Base::cancel()
    {
        for(int i = 0;i<pidList.getLen();++i)
        {
            pthread_t* pPid = pidList[i];
            pthread_cancel(*pPid);
            delete pPid;
            pPid = pidList[i] = NULL;
        }
    }
    
    void GC_Task_Base::active(int num)
    {
        
        pthread_attr_t attr;
        pthread_t* pPid;
        pthread_attr_init(&attr);
        pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
        
        for(int i= 0;i<num;++i)
        {
            pPid = new pthread_t;
            pthread_create(pPid, NULL, svc_run, (void*)this);
            pidList.add(pPid);
        }
        
        return;
    }
    
    void* GC_Task_Base::svc_run(void* arg)
    {
        GC_Task_Base* pTask = (GC_Task_Base*) arg;
        
        if(pTask)
        {
            //cout<<"GC_Task_Base::svc_run start up"<<endl;
            pTask->svc();
        }
        else
        {
            // Raise a runtime error
        }
        return NULL;
    }
}